package com.woniuxy.shiro;

import com.woniuxy.JwtUtils.JWTUtils;
import com.woniuxy.entity.RbacManager;
import com.woniuxy.service.RbacManagerService;
import com.woniuxy.service.RbacPermService;
import com.woniuxy.service.RbacRoleService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import java.util.Set;


//自定义域: 校验token的有效性！

@Configuration
public class MyRealm extends AuthorizingRealm {
    @Autowired
    RbacManagerService rbacManagerService;
    @Autowired
    RbacRoleService rbacRoleService;
    @Autowired
    RbacPermService rbacPermService;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof MyJsonWebToken;
    }
//     授权
//     @param principals就是是JWT的token
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //通过下面的认证方法SimpleAuthenticationInfo对象中的凭证获取到token的值！
        String token = principals.getPrimaryPrincipal()+"";
        String username = JWTUtils.getUsername(token);
        //查询当前登录的subject用户的角色
        String roleName = rbacRoleService.findByRbacManager(username);
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRole(roleName);
        //查询当前登录的subject的权限集合
        Set<String> perms = rbacPermService.findByUsername(username);
        simpleAuthorizationInfo.setStringPermissions(perms);
        return simpleAuthorizationInfo;
    }

//     认证
//     @param jwtToken JWT的token 昨天传入的是UsernamePasswordToken
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken jwtToken) throws AuthenticationException {
        //通过token获取我们自定义的MyJsonWebToken中存入的token
        String token = jwtToken.getPrincipal()+"";

        //从token中拿出用户名 后面篡改token的body值，来尝试，看能够获取到username，不先校验的情况
        String username = JWTUtils.getUsername(token);
        if ("".equals(username)){
            throw new  AuthenticationException("用户信息不对！");
        }
        //调用service，查询数据库，获取用户信息
        RbacManager user = rbacManagerService.findUser(username);
        //这一步是校验用户名密码是否正确
        boolean verify = JWTUtils.verify(token, username, user.getPassword());
        if (verify){//说明代码没有问题
            return new SimpleAuthenticationInfo(token,token,"myRealm");
        }
        return null;
    }
}
